﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.ComponentModel;
using ActiveUp.Net.Mail;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace MailProcessing
{
    public class ApplicationFacade
    {
        private static ApplicationFacade facade;
        private const string TEMP_DATA_FOLDER = "DataTemp";
        protected MailAccountInfo _mailAccountInfo;
        protected Pop3Controller _pop3Controller;
        protected CSVProcessing _csvProcessing;
        private ZipController _zipController;
        
        private string GetApplicationPath()
        {
            return System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Replace(@"file:\", string.Empty);
        }
        private DateTime _lastDateTime;
        protected DateTime LastDateTime
        {
            get 
            {
                DateTime returnValue = DateTime.MinValue;
                if (_lastDateTime == DateTime.MinValue)
                {
                    string fileName = Path.Combine(GetApplicationPath(), "LastTimeRetrieveMail.hai");
                    Stream stream = null;
                    if (File.Exists(fileName))
                    {
                        try
                        {
                            IFormatter formatter = new BinaryFormatter();
                            stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                            returnValue = (DateTime)formatter.Deserialize(stream);
                            _lastDateTime = returnValue;
                        }
                        catch (Exception ex)
                        {

                        }
                        finally {
                            if( stream != null)
                                stream.Close();
                        }
                    }
                  
                    
                }
                return returnValue;
            }
            set
            {
                _lastDateTime = value;
                string fileName = Path.Combine(GetApplicationPath(), "LastTimeRetrieveMail.hai");
                if (File.Exists(fileName))
                    File.Delete(fileName);
                IFormatter formatter = new BinaryFormatter();
                Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
                formatter.Serialize(stream, _lastDateTime);
                stream.Close();
            }
        }
        protected FTPController _ftpController;
        private string _tempFolderPath;
        private ApplicationFacade()
        {
            _mailAccountInfo = MailAccountInfo.FillMailAccountInfo();
            _pop3Controller = new Pop3Controller(_mailAccountInfo);
            _csvProcessing = new CSVProcessing();
            _zipController = new ZipController();
            _ftpController = new FTPController(FTPSettings.GetInstance());
            _lastDateTime = DateTime.MinValue;
            InitilizeBasePath();            
        }

        private void InitilizeBasePath()
        {
            _tempFolderPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
            //_tempFolderPath = @"D:\Program Files\Mail_processing\Source_Code\MailProcessing";
            _tempFolderPath = _tempFolderPath.Replace(@"file:\", string.Empty);
            _tempFolderPath = Path.Combine(_tempFolderPath, TEMP_DATA_FOLDER);
            if(!Directory.Exists(_tempFolderPath))
            {
                Directory.CreateDirectory(_tempFolderPath);
            }
        }
        public static ApplicationFacade GetInstance() {
            try
            {
                if (facade == null)
                    facade = new ApplicationFacade();
            }
            catch(Exception ex)
            {
                DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
            }         
            return facade;
        }
        
        
        public virtual void ProcessingAllMailMessages()
        {
            //get mails
            int messageCount = _pop3Controller.GetMessageCount();
            int i = messageCount;
            bool needSaveLastTime = true;
            while (i > 0)
            {
                Message message = _pop3Controller.GetMessage(i);
                if (message.ReceivedDate > LastDateTime)
                {
                    if (message.Attachments.Count > 0)
                    {
                        if (ProcessingMessage(message))
                        {
                            if (i == messageCount)
                            {
                                needSaveLastTime = false;
                                LastDateTime = message.ReceivedDate;
                            }
                            _pop3Controller.DeleteMessage(i);
                            break;
                        }
                    }
                }
                else
                {
                    if (i == messageCount)
                    {
                        needSaveLastTime = false;
                        break;
                    }
                }
                i--;
            }
            if(needSaveLastTime)
                LastDateTime = _pop3Controller.GetMessage(_pop3Controller.GetMessageCount()).ReceivedDate;
            this._pop3Controller.UpdateStats();
            this._pop3Controller.Disconnect();
        }
        protected virtual bool ProcessingMessage(Message mailMessage)
        {
            bool isUploaded = false;
            foreach (MimePart attachment in mailMessage.Attachments)
            {
                if (attachment.ContentType.MimeType.ToLower().Equals(@"application/zip"))
                {                    
                    string filepath = attachment.StoreToFile(Path.Combine(_tempFolderPath, attachment.Filename));
                    string unzipFolder;
                    if (_zipController.Unzipfile(filepath, out unzipFolder))
                    {
                        string[] files = Directory.GetFiles(unzipFolder);
                        foreach (string file in files)
                        {
                            if (Path.GetExtension(file).ToLower().Contains("csv"))
                            {
                                string maxNumberReturn = _csvProcessing.ProcessFileAndReturnMaxNumber(file);
                                if (_ftpController.FtpUploadFile(maxNumberReturn))
                                {
                                    isUploaded = true;
                                    break;
                                }
                            }
                        }
                        foreach (string file in files)
                        {
                            File.Delete(file);
                        }
                        if(Directory.Exists(unzipFolder))
                        {
                            Directory.Delete(unzipFolder);
                        }
                        
                        if (isUploaded)
                            return isUploaded;
                    }
                    else
                    {
                        File.Delete(filepath);                        
                    }
                }
            }
            return isUploaded;
        }
    }
}
